-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local log = require 'mc.logging'

local model_coefficients = {
    [0x0000] = 0,
    [0x0001] = 0,
    [0x0002] = 0,
    [0x0003] = 0,
    [0x0004] = 0,
    [0x0005] = 0,
    [0x0006] = 0,
    [0x0007] = 0,
    [0x0010] = 0,
    [0x0011] = 0,
    [0x0012] = 0,
    [0x0013] = 0,
    [0x0014] = 0,
    [0x0015] = 0,
    [0x0016] = 0,
    [0x0017] = 0,
    [0x0020] = 0,
    [0x0021] = 0,
    [0x0022] = 0,
    [0x0023] = 0,
    [0x0024] = 0,
    [0x0025] = 0,
    [0x0026] = 0,
    [0x0027] = 0,
    [0x0030] = 0,
    [0x0031] = 0,
    [0x0032] = 0,
    [0x0033] = 0,
    [0x0034] = 0,
    [0x0035] = 0,
    [0x0036] = 0,
    [0x0037] = 0,
    [0x0040] = 0,
    [0x0041] = 0,
    [0x0042] = 0,
    [0x0043] = 0,
    [0x0044] = 0,
    [0x0045] = 0,
    [0x0046] = 0,
    [0x0047] = 0,
    [0x0050] = 0,
    [0x0051] = 0,
    [0x0052] = 0,
    [0x0053] = 0,
    [0x0054] = 0,
    [0x0055] = 0,
    [0x0056] = 0,
    [0x0057] = 0,
    [0x0100] = 4.76,
    [0x0101] = 7.32,
    [0x0102] = 11.1,
    [0x0103] = 16.62,
    [0x0104] = 24.56,
    [0x0105] = 35.86,
    [0x0106] = 51.75,
    [0x0107] = 73.88,
    [0x0110] = 1.19,
    [0x0111] = 1.83,
    [0x0112] = 2.78,
    [0x0113] = 4.15,
    [0x0114] = 6.14,
    [0x0115] = 8.96,
    [0x0116] = 12.94,
    [0x0117] = 18.47,
    [0x0120] = 0.53,
    [0x0121] = 0.81,
    [0x0122] = 1.23,
    [0x0123] = 1.84,
    [0x0124] = 2.72,
    [0x0125] = 3.98,
    [0x0126] = 5.74,
    [0x0127] = 8.19,
    [0x0130] = 0.30,
    [0x0131] = 0.46,
    [0x0132] = 0.69,
    [0x0133] = 1.04,
    [0x0134] = 1.53,
    [0x0135] = 2.24,
    [0x0136] = 3.23,
    [0x0137] = 4.62,
    [0x0140] = 0.1,
    [0x0141] = 0.15,
    [0x0142] = 0.22,
    [0x0143] = 0.34,
    [0x0144] = 0.5,
    [0x0145] = 0.72,
    [0x0146] = 1.04,
    [0x0147] = 1.49,
    [0x0150] = 0.05,
    [0x0151] = 0.07,
    [0x0152] = 0.11,
    [0x0153] = 0.17,
    [0x0154] = 0.25,
    [0x0155] = 0.36,
    [0x0156] = 0.52,
    [0x0157] = 0.74,
    [0x0200] = 4.76,
    [0x0201] = 7.32,
    [0x0202] = 11.1,
    [0x0203] = 16.62,
    [0x0204] = 24.56,
    [0x0205] = 35.86,
    [0x0206] = 51.75,
    [0x0207] = 73.88,
    [0x0210] = 1.19,
    [0x0211] = 1.83,
    [0x0212] = 2.78,
    [0x0213] = 4.15,
    [0x0214] = 6.14,
    [0x0215] = 8.96,
    [0x0216] = 12.94,
    [0x0217] = 18.47,
    [0x0220] = 0.53,
    [0x0221] = 0.81,
    [0x0222] = 1.23,
    [0x0223] = 1.84,
    [0x0224] = 2.72,
    [0x0225] = 3.98,
    [0x0226] = 5.74,
    [0x0227] = 8.19,
    [0x0230] = 0.3,
    [0x0231] = 0.46,
    [0x0232] = 0.69,
    [0x0233] = 1.04,
    [0x0234] = 1.53,
    [0x0235] = 2.24,
    [0x0236] = 3.23,
    [0x0237] = 4.62,
    [0x0240] = 0.1,
    [0x0241] = 0.15,
    [0x0242] = 0.22,
    [0x0243] = 0.34,
    [0x0244] = 0.5,
    [0x0245] = 0.72,
    [0x0246] = 1.04,
    [0x0247] = 1.49,
    [0x0250] = 0.05,
    [0x0251] = 0.07,
    [0x0252] = 0.11,
    [0x0253] = 0.17,
    [0x0254] = 0.25,
    [0x0255] = 0.36,
    [0x0256] = 0.52,
    [0x0257] = 0.74,
    [0x0300] = 4.76,
    [0x0301] = 7.32,
    [0x0302] = 11.1,
    [0x0303] = 16.62,
    [0x0304] = 24.56,
    [0x0305] = 35.86,
    [0x0306] = 51.75,
    [0x0307] = 73.88,
    [0x0310] = 1.19,
    [0x0311] = 1.83,
    [0x0312] = 2.78,
    [0x0313] = 4.15,
    [0x0314] = 6.14,
    [0x0315] = 8.96,
    [0x0316] = 12.94,
    [0x0317] = 18.47,
    [0x0320] = 0.53,
    [0x0321] = 0.81,
    [0x0322] = 1.23,
    [0x0323] = 1.84,
    [0x0324] = 2.72,
    [0x0325] = 3.98,
    [0x0326] = 5.74,
    [0x0327] = 8.19,
    [0x0330] = 0.3,
    [0x0331] = 0.46,
    [0x0332] = 0.69,
    [0x0333] = 1.04,
    [0x0334] = 1.53,
    [0x0335] = 2.24,
    [0x0336] = 3.23,
    [0x0337] = 4.62,
    [0x0340] = 0.1,
    [0x0341] = 0.15,
    [0x0342] = 0.22,
    [0x0343] = 0.34,
    [0x0344] = 0.5,
    [0x0345] = 0.72,
    [0x0346] = 1.04,
    [0x0347] = 1.49,
    [0x0350] = 0.05,
    [0x0351] = 0.07,
    [0x0352] = 0.11,
    [0x0353] = 0.17,
    [0x0354] = 0.25,
    [0x0355] = 0.36,
    [0x0356] = 0.52,
    [0x0357] = 0.74,
    [0x0400] = 4.76,
    [0x0401] = 7.32,
    [0x0402] = 11.1,
    [0x0403] = 16.62,
    [0x0404] = 24.56,
    [0x0405] = 35.86,
    [0x0406] = 51.75,
    [0x0407] = 73.88,
    [0x0410] = 1.19,
    [0x0411] = 1.83,
    [0x0412] = 2.78,
    [0x0413] = 4.15,
    [0x0414] = 6.14,
    [0x0415] = 8.96,
    [0x0416] = 12.94,
    [0x0417] = 18.47,
    [0x0420] = 0.53,
    [0x0421] = 0.81,
    [0x0422] = 1.23,
    [0x0423] = 1.84,
    [0x0424] = 2.72,
    [0x0425] = 3.98,
    [0x0426] = 5.74,
    [0x0427] = 8.19,
    [0x0430] = 0.3,
    [0x0431] = 0.46,
    [0x0432] = 0.69,
    [0x0433] = 1.04,
    [0x0434] = 1.53,
    [0x0435] = 2.24,
    [0x0436] = 3.23,
    [0x0437] = 4.62,
    [0x0440] = 0.1,
    [0x0441] = 0.15,
    [0x0442] = 0.22,
    [0x0443] = 0.34,
    [0x0444] = 0.5,
    [0x0445] = 0.72,
    [0x0446] = 1.04,
    [0x0447] = 1.49,
    [0x0450] = 0.05,
    [0x0451] = 0.07,
    [0x0452] = 0.11,
    [0x0453] = 0.17,
    [0x0454] = 0.25,
    [0x0455] = 0.36,
    [0x0456] = 0.52,
    [0x0457] = 0.74
}

local function predicted_lifespan(model_params)
    if not model_params or type(model_params) ~= "table" then
        log:error('incorrect model parameter format')
        return nil
    end
    local weight_coefficient_sum = 0
    local model_coefficient
    for model_index, param in pairs(model_params) do
        model_coefficient = model_coefficients[model_index]
        if not model_coefficient then
            log:error('get model coefficient failed, invalid index: %s', model_index)
            return nil
        end
        weight_coefficient_sum = weight_coefficient_sum + (model_coefficient * param)
    end
    -- 寿命公式 = 2.6亿 - Σ（充放电次数 * 加权系数）
    return math.ceil(260000000 - weight_coefficient_sum)
end

local function get_model_level()
    -- 放电深度5个档、频率6个档、温度8个档
    return 5 << 8 | 6 << 4 | 8
end

return { predicted_lifespan = predicted_lifespan, get_model_level = get_model_level }